From 8be47dac0fc88acbf4e918cb2f83e06060d2c73d Mon Sep 17 00:00:00 2001 From: "cl349@freefall.cl.cam.ac.uk" Date: Tue, 7 Sep 2004 09:59:39 +0000 Subject: [PATCH] bitkeeper revision 1.1159.1.129 (413d868bPMWkW0lZg_MuAYIrmx7XDQ) Make writable pagetables a domain creation option. --- .../arch/xen/i386/kernel/head.S | 10 +++- .../arch/xen/i386/kernel/setup.c | 4 -- xen/arch/x86/domain.c | 46 ++++++++++--------- xen/common/domain.c | 22 +++++++++ xen/common/elf.c | 18 ++++---- xen/common/kernel.c | 19 +------- xen/include/asm-x86/mm.h | 4 +- xen/include/xen/elf.h | 4 +- xen/include/xen/lib.h | 3 ++ xen/include/xen/sched.h | 10 ++++ 10 files changed, 80 insertions(+), 60 deletions(-) diff --git a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/head.S b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/head.S index ff81f18dd9..be45eec5c4 100644 --- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/head.S +++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/head.S @@ -1,9 +1,15 @@ +#include + .section __xen_guest - .asciz "GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=2.0" + .ascii "GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=2.0" + .ascii ",LOADER=generic" +#ifdef CONFIG_XEN_WRITABLE_PAGETABLES + .ascii ",PT_MODE_WRITABLE" +#endif + .byte 0 .text -#include #include #include #include diff --git a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/setup.c index 1a1c3376d9..22f1dab651 100644 --- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/setup.c @@ -1295,10 +1295,6 @@ void __init setup_arch(char **cmdline_p) HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); -#ifdef CONFIG_XEN_WRITABLE_PAGETABLES - HYPERVISOR_vm_assist(VMASST_CMD_enable, - VMASST_TYPE_writable_pagetables); -#endif pm_idle = xen_cpu_idle; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 868a3c97ad..d66d407aab 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -557,10 +557,7 @@ int construct_dom0(struct domain *p, * *_start address are page-aligned, except v_start (and v_end) which are * superpage-aligned. */ - unsigned long v_start; - unsigned long vkern_start; - unsigned long vkern_entry; - unsigned long vkern_end; + struct domain_setup_info dsi; unsigned long vinitrd_start; unsigned long vinitrd_end; unsigned long vphysmap_start; @@ -584,6 +581,8 @@ int construct_dom0(struct domain *p, if ( test_bit(DF_CONSTRUCTED, &p->flags) ) BUG(); + memset(&dsi, 0, sizeof(struct domain_setup_info)); + printk("*** LOADING DOMAIN 0 ***\n"); /* @@ -598,12 +597,11 @@ int construct_dom0(struct domain *p, * We'll have to revisit this if we ever support PAE (64GB). */ - rc = parseelfimage(image_start, image_len, &v_start, - &vkern_start, &vkern_end, &vkern_entry); + rc = parseelfimage(image_start, image_len, &dsi); if ( rc != 0 ) return rc; - if ( (v_start & (PAGE_SIZE-1)) != 0 ) + if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 ) { printk("Initial guest OS must load to a page boundary.\n"); return -EINVAL; @@ -618,7 +616,7 @@ int construct_dom0(struct domain *p, */ for ( nr_pt_pages = 2; ; nr_pt_pages++ ) { - vinitrd_start = round_pgup(vkern_end); + vinitrd_start = round_pgup(dsi.v_kernend); vinitrd_end = vinitrd_start + initrd_len; vphysmap_start = round_pgup(vinitrd_end); vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); @@ -631,7 +629,7 @@ int construct_dom0(struct domain *p, v_end = (vstack_end + (1<<22)-1) & ~((1<<22)-1); if ( (v_end - vstack_end) < (512 << 10) ) v_end += 1 << 22; /* Add extra 4MB to get >= 512kB padding. */ - if ( (((v_end - v_start + ((1<> + if ( (((v_end - dsi.v_start + ((1<> L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages ) break; } @@ -651,20 +649,20 @@ int construct_dom0(struct domain *p, " Start info: %08lx->%08lx\n" " Boot stack: %08lx->%08lx\n" " TOTAL: %08lx->%08lx\n", - vkern_start, vkern_end, + dsi.v_kernstart, dsi.v_kernend, vinitrd_start, vinitrd_end, vphysmap_start, vphysmap_end, vpt_start, vpt_end, vstartinfo_start, vstartinfo_end, vstack_start, vstack_end, - v_start, v_end); - printk(" ENTRY ADDRESS: %08lx\n", vkern_entry); + dsi.v_start, v_end); + printk(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry); - if ( (v_end - v_start) > (nr_pages * PAGE_SIZE) ) + if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) ) { printk("Initial guest OS requires too much space\n" "(%luMB is greater than %luMB limit)\n", - (v_end-v_start)>>20, (nr_pages<>20); + (v_end-dsi.v_start)>>20, (nr_pages<>20); return -ENOMEM; } @@ -672,7 +670,7 @@ int construct_dom0(struct domain *p, * Protect the lowest 1GB of memory. We use a temporary mapping there * from which we copy the kernel and ramdisk images. */ - if ( v_start < (1<<30) ) + if ( dsi.v_start < (1<<30) ) { printk("Initial loading isn't allowed to lowest 1GB of memory.\n"); return -EINVAL; @@ -691,7 +689,7 @@ int construct_dom0(struct domain *p, p->tot_pages++; p->max_pages++; } - mpt_alloc = (vpt_start - v_start) + alloc_start; + mpt_alloc = (vpt_start - dsi.v_start) + alloc_start; SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES); SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS); @@ -715,9 +713,9 @@ int construct_dom0(struct domain *p, mk_l2_pgentry(__pa(p->mm.perdomain_pt) | __PAGE_HYPERVISOR); p->mm.pagetable = mk_pagetable((unsigned long)l2start); - l2tab += l2_table_offset(v_start); + l2tab += l2_table_offset(dsi.v_start); mfn = alloc_start >> PAGE_SHIFT; - for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ) + for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ ) { if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) ) { @@ -726,7 +724,7 @@ int construct_dom0(struct domain *p, *l2tab++ = mk_l2_pgentry((unsigned long)l1start | L2_PROT); clear_page(l1tab); if ( count == 0 ) - l1tab += l1_table_offset(v_start); + l1tab += l1_table_offset(dsi.v_start); } *l1tab++ = mk_l1_pgentry((mfn << PAGE_SHIFT) | L1_PROT); @@ -762,7 +760,7 @@ int construct_dom0(struct domain *p, page->u.inuse.type_info &= ~PGT_type_mask; page->u.inuse.type_info |= PGT_l1_page_table; page->u.inuse.type_info |= - ((v_start>>L2_PAGETABLE_SHIFT)+(count-1))<>L2_PAGETABLE_SHIFT)+(count-1))<shared_info); p->shared_info->domain_time = 0; @@ -804,7 +806,7 @@ int construct_dom0(struct domain *p, { mfn = pfn + (alloc_start>>PAGE_SHIFT); #ifndef NDEBUG -#define REVERSE_START ((v_end - v_start) >> PAGE_SHIFT) +#define REVERSE_START ((v_end - dsi.v_start) >> PAGE_SHIFT) if ( pfn > REVERSE_START ) mfn = (alloc_end>>PAGE_SHIFT) - (pfn - REVERSE_START); #endif @@ -854,7 +856,7 @@ int construct_dom0(struct domain *p, shadow_mode_enable(&p->mm, SHM_test); #endif - new_thread(p, vkern_entry, vstack_end, vstartinfo_start); + new_thread(p, dsi.v_kernentry, vstack_end, vstartinfo_start); return 0; } diff --git a/xen/common/domain.c b/xen/common/domain.c index f64d21e711..d8ac21a688 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -308,3 +308,25 @@ int final_setup_guestos(struct domain *p, dom0_builddomain_t *builddomain) xfree(c); return rc; } + +long vm_assist(struct domain *p, unsigned int cmd, unsigned int type) +{ + if ( type > MAX_VMASST_TYPE ) + return -EINVAL; + + switch ( cmd ) + { + case VMASST_CMD_enable: + set_bit(type, &p->vm_assist); + if (vm_assist_info[type].enable) + (*vm_assist_info[type].enable)(p); + return 0; + case VMASST_CMD_disable: + clear_bit(type, &p->vm_assist); + if (vm_assist_info[type].disable) + (*vm_assist_info[type].disable)(p); + return 0; + } + + return -ENOSYS; +} diff --git a/xen/common/elf.c b/xen/common/elf.c index ae20c04f6f..7f5a11e351 100644 --- a/xen/common/elf.c +++ b/xen/common/elf.c @@ -18,10 +18,7 @@ static inline int is_loadable_phdr(Elf_Phdr *phdr) int parseelfimage(char *elfbase, unsigned long elfsize, - unsigned long *pvirtstart, - unsigned long *pkernstart, - unsigned long *pkernend, - unsigned long *pkernentry) + struct domain_setup_info *dsi) { Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase; Elf_Phdr *phdr; @@ -109,13 +106,16 @@ int parseelfimage(char *elfbase, return -EINVAL; } - *pvirtstart = kernstart; + dsi->v_start = kernstart; if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL ) - *pvirtstart = simple_strtoul(p+10, &p, 0); + dsi->v_start = simple_strtoul(p+10, &p, 0); - *pkernstart = kernstart; - *pkernend = kernend; - *pkernentry = ehdr->e_entry; + if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL ) + dsi->use_writable_pagetables = 1; + + dsi->v_kernstart = kernstart; + dsi->v_kernend = kernend; + dsi->v_kernentry = ehdr->e_entry; return 0; } diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 9b2a3cd70c..1baef5caa9 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -365,24 +365,7 @@ long do_xen_version(int cmd) long do_vm_assist(unsigned int cmd, unsigned int type) { - if ( type > MAX_VMASST_TYPE ) - return -EINVAL; - - switch ( cmd ) - { - case VMASST_CMD_enable: - set_bit(type, ¤t->vm_assist); - if (vm_assist_info[type].enable) - (*vm_assist_info[type].enable)(); - return 0; - case VMASST_CMD_disable: - clear_bit(type, ¤t->vm_assist); - if (vm_assist_info[type].disable) - (*vm_assist_info[type].disable)(); - return 0; - } - - return -ENOSYS; + return vm_assist(current, cmd, type); } long do_ni_hypercall(void) diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 894130d143..ec0f88cee6 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -363,8 +363,8 @@ int memguard_is_guarded(void *p); typedef struct { - void (*enable)(void); - void (*disable)(void); + void (*enable)(struct domain *); + void (*disable)(struct domain *); } vm_assist_info_t; extern vm_assist_info_t vm_assist_info[]; diff --git a/xen/include/xen/elf.h b/xen/include/xen/elf.h index 2abd8a2206..9e474367b7 100644 --- a/xen/include/xen/elf.h +++ b/xen/include/xen/elf.h @@ -525,8 +525,6 @@ typedef struct { #endif extern int loadelfimage(char *); -extern int parseelfimage( - char *, unsigned long, unsigned long *, - unsigned long *, unsigned long *, unsigned long *); +extern int parseelfimage(char *, unsigned long, struct domain_setup_info *); #endif /* __XEN_ELF_H__ */ diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index e9893a2f6f..362ea007a1 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -14,10 +14,13 @@ #define reserve_bootmem(_p,_l) \ printk("Memory Reservation 0x%lx, %lu bytes\n", (_p), (_l)) +struct domain; + /* kernel.c */ #define printk printf void printf(const char *format, ...); void panic(const char *format, ...); +long vm_assist(struct domain *, unsigned int, unsigned int); /* vsprintf.c */ extern int sprintf(char * buf, const char * fmt, ...) diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 51fb070673..99368a7a12 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -146,6 +146,16 @@ struct domain atomic_t pausecnt; }; +struct domain_setup_info +{ + unsigned long v_start; + unsigned long v_kernstart; + unsigned long v_kernend; + unsigned long v_kernentry; + + unsigned int use_writable_pagetables; +}; + #include /* for KERNEL_DS */ extern struct domain idle0_task; -- 2.30.2